package designModel;

// 模板方法（TemplateMethod）模式：定义一个操作中的算法骨架，而将算法的一些步骤延迟到子类中，使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 ☆☆☆☆☆
public class TemplateMethod {
    public static void main(String[] args) {
        Game game = new Agame();
        game.play();
        game = new Football();
        game.play();
    }
}

//当你在设计一个类或一组类时，发现有一些算法的结构是固定的，但其中的某些步骤可能会因应用情境或子类的不同而变化。
//你希望将这个算法的核心结构固定下来，但留出一些灵活性来允许特定步骤的定制。

//解决方案：
//模板方法模式通过定义一个抽象的父类，其中包含了算法的核心结构，但某些步骤使用抽象方法或受保护的虚拟方法来表示，这些方法由子类来实现。
//这使得子类可以根据需要重写特定的步骤，而核心算法结构保持不变。父类中的模板方法调用这些步骤，确保算法的整体流程一致。

abstract class Game {
    // 允许子类重写的方法(非固定步骤)
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();

    // 固定步骤1
    void first(){
        System.out.println("第一步");
    }
    // 固定步骤2
    void second(){
        System.out.println("第二步");
    }
    //模板 方法不允许子类覆盖
    public final void play(){
        //初始化游戏
        initialize();
        first();
        //开始游戏
        startPlay();
        //结束游戏
        second();
        endPlay();
    }
}

class Agame extends Game{
    // 重写的方法可以是空方法 表示 某个步骤 为空 可以跳过
    @Override
    void initialize() {
        System.out.println("initialize");
    }

    @Override
    void startPlay() {
        System.out.println("startPlay");
    }

    @Override
    void endPlay() {
        System.out.println("endPlay");
    }
}
class Football extends Game {

    @Override
    void endPlay() {
        System.out.println("Football Game Finished!");
    }

    @Override
    void initialize() {
        System.out.println("Football Game Initialized! Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Football Game Started. Enjoy the game!");
    }
}